/**
 * 
 * Copyright (C) 2011 Cody Stoutenburg . All rights reserved.
 *
 *       This program is free software; you can redistribute it and/or
 *       modify it under the terms of the GNU Lesser General Public License
 *       as published by the Free Software Foundation; either version 2.1
 *       of the License, or (at your option) any later version.
 *
 *       This program is distributed in the hope that it will be useful,
 *       but WITHOUT ANY WARRANTY; without even the implied warranty of
 *       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *       GNU Lesser General Public License for more details.
 *
 *       You should have received a copy of the GNU Lesser General Public License
 *       along with this program; if not, write to the Free Software
 *       Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. 
 * 
 */
package ca.usherbrooke.model.world;

import java.io.Serializable;
import java.util.List;

import org.newdawn.slick.geom.Rectangle;

import ca.usherbrooke.model.bridge.IEntityModelObject;
import ca.usherbrooke.model.bridge.IEquipmentModelObject;
import ca.usherbrooke.model.entity.IEntityModel;
import ca.usherbrooke.model.equipment.EquipmentModel;
import ca.usherbrooke.model.feature.FeatureModel;
import ca.usherbrooke.model.feature.GroundModel;
import ca.usherbrooke.model.feature.WallModel;
import ca.usherbrooke.tools.position.Vector2D;

/**
 * the world is a 2D tiled map.<br/>
 * the world is composed with grounds elements that can be
 * <code>GroundModel</code> or <code>WallModel</code>.
 * 
 * the world contain a list of equipments<br/>
 * the world contain a list of entity
 * 
 * @author Cody Stoutenburg
 * @version 1.0
 * 
 */
public interface IWorldModel extends Serializable {

	/**
	 * a rectangle that represent the size of the world
	 * 
	 * @return the size of the world
	 */
	Rectangle getSize();

	/**
	 * get the tile ground at the position x, y
	 * 
	 * @param x
	 *            the tile number x
	 * @param y
	 *            the tile number y
	 * @return the tile at that position or null if no tile
	 */
	FeatureModel getTileAt(int x, int y);

	/**
	 * get the width of a tile
	 * 
	 * @return the width of a tile
	 */
	int getTileWidth();

	/**
	 * get the height of a tile
	 * 
	 * @return the height of a tile
	 */
	int getTileHeight();

	/**
	 * get the entity with this guid
	 * 
	 * @param guid
	 * @return the entity or null if no entity found
	 */
	IEntityModel getEntity(Long guid);

	/**
	 * get the entity at this position
	 * 
	 * @param position
	 * @return the entity or null if no entity found
	 */
	IEntityModel getEntity(Vector2D position);

	/**
	 * get all entities that the world contain
	 * 
	 * @return all entities in the world
	 */
	List<IEntityModel> getAllEntities();

	/**
	 * get all entities that are in the rectangle
	 * 
	 * @param position
	 * @return all entities in the rectangle or an empty list if no entities
	 */
	List<IEntityModel> getEntities(Rectangle position);

	/**
	 * get the equipment with this guid
	 * 
	 * @param guid
	 * @return the equipment or null if no equipment have this guid
	 */
	EquipmentModel getEquipment(Long guid);

	/**
	 * get all equipments that the world contain
	 * 
	 * @return all equipment in world or an empty list
	 */
	List<EquipmentModel> getAllEquipments();

	/**
	 * get the equipments at this position
	 * 
	 * @param position
	 * @return all equipment at this position or an empty list
	 */
	List<EquipmentModel> getEquipment(Vector2D position);

	/**
	 * get all equipments that are in the rectangle
	 * 
	 * @param position
	 * @return all equipment in the rectangle or an empty list
	 */
	List<EquipmentModel> getEquipment(Rectangle position);

	/**
	 * get the ground at this position
	 * 
	 * @param position
	 * @return the ground at that position or null if no ground
	 */
	GroundModel getGround(Vector2D position);

	/**
	 * get the wall at this position
	 * 
	 * @param position
	 * @return the wall at that position or null if no wall
	 */
	WallModel getWall(Vector2D position);

	/**
	 * get all wall that are in the rectangle
	 * 
	 * @param position
	 * @return all wall that are in the rectangle
	 */
	List<WallModel> getWall(Rectangle position);

	/**
	 * get the real time elapse since the simulation start
	 * 
	 * @return the time elapse in ms
	 */
	Long getRealTimeElapse();

	/**
	 * Update the world with delta in ms
	 * 
	 * @param delta
	 *            time in ms
	 */
	void update(int delta);

	/**
	 * create an equipment in the world
	 * 
	 * @param equipement
	 * @return create an equipment in the world
	 */
	EquipmentModel createEquipment(IEquipmentModelObject equipement);

	/**
	 * create an entity in the world
	 * 
	 * @param entity
	 * @return create an entity in the world
	 */
	IEntityModel createEntity(IEntityModelObject entity);

	/**
	 * get a sub world that view the entity
	 * 
	 * @param guid
	 * @return the sub world that the entity view
	 */
	IWorldModel getVision(Long guid);

	/**
	 * get a copy of the world for transfer
	 * 
	 * @return a copy of the world for transfer
	 */
	IWorldModel copyToTransfert();
}
